From fecf986bf29594a88fce2ae67530780a9b670faf Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Fri, 16 Nov 2007 16:22:00 +0000 Subject: [PATCH] x86, hvm: Small code cleanups. Based on patch from Xin Li. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/hvm.c | 10 +++--- xen/arch/x86/hvm/vmx/vmx.c | 68 ++++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 40 deletions(-) diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index cb4b37bad0..ec7344b06b 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -667,7 +667,7 @@ int hvm_set_cr0(unsigned long value) struct vcpu *v = current; p2m_type_t p2mt; unsigned long gfn, mfn, old_value = v->arch.hvm_vcpu.guest_cr[0]; - + HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx", value); if ( (u32)value != value ) @@ -684,7 +684,7 @@ int hvm_set_cr0(unsigned long value) /* ET is reserved and should be always be 1. */ value |= X86_CR0_ET; - if ( (value & (X86_CR0_PE|X86_CR0_PG)) == X86_CR0_PG ) + if ( (value & (X86_CR0_PE | X86_CR0_PG)) == X86_CR0_PG ) { hvm_inject_exception(TRAP_gp_fault, 0, 0); return 0; @@ -710,10 +710,10 @@ int hvm_set_cr0(unsigned long value) /* The guest CR3 must be pointing to the guest physical. */ gfn = v->arch.hvm_vcpu.guest_cr[3]>>PAGE_SHIFT; mfn = mfn_x(gfn_to_mfn_current(gfn, &p2mt)); - if ( !p2m_is_ram(p2mt) || !mfn_valid(mfn) || + if ( !p2m_is_ram(p2mt) || !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain)) { - gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n", + gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n", v->arch.hvm_vcpu.guest_cr[3], mfn); domain_crash(v->domain); return 0; @@ -742,7 +742,7 @@ int hvm_set_cr0(unsigned long value) } } - if ( !list_empty(&(domain_hvm_iommu(v->domain)->pdev_list)) ) + if ( !list_empty(&domain_hvm_iommu(v->domain)->pdev_list) ) { if ( (value & X86_CR0_CD) && !(value & X86_CR0_NW) ) { diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index b44cab7885..348e69c5e0 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -518,26 +518,18 @@ void vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c) vmx_vmcs_exit(v); } -int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c) +static int vmx_restore_cr0_cr3( + struct vcpu *v, unsigned long cr0, unsigned long cr3) { unsigned long mfn = 0; p2m_type_t p2mt; - if ( c->pending_valid && - ((c->pending_type == 1) || (c->pending_type > 6) || - (c->pending_reserved != 0)) ) + if ( cr0 & X86_CR0_PG ) { - gdprintk(XENLOG_ERR, "Invalid pending event 0x%"PRIx32".\n", - c->pending_event); - return -EINVAL; - } - - if ( c->cr0 & X86_CR0_PG ) - { - mfn = mfn_x(gfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT, &p2mt)); + mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt)); if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) ) { - gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64"\n", c->cr3); + gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%lx\n", cr3); return -EINVAL; } } @@ -547,11 +539,32 @@ int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c) v->arch.guest_table = pagetable_from_pfn(mfn); + v->arch.hvm_vcpu.guest_cr[0] = cr0 | X86_CR0_ET; + v->arch.hvm_vcpu.guest_cr[3] = cr3; + + return 0; +} + +int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c) +{ + int rc; + + if ( c->pending_valid && + ((c->pending_type == 1) || (c->pending_type > 6) || + (c->pending_reserved != 0)) ) + { + gdprintk(XENLOG_ERR, "Invalid pending event 0x%"PRIx32".\n", + c->pending_event); + return -EINVAL; + } + + rc = vmx_restore_cr0_cr3(v, c->cr0, c->cr3); + if ( rc ) + return rc; + vmx_vmcs_enter(v); - v->arch.hvm_vcpu.guest_cr[0] = c->cr0 | X86_CR0_ET; v->arch.hvm_vcpu.guest_cr[2] = c->cr2; - v->arch.hvm_vcpu.guest_cr[3] = c->cr3; v->arch.hvm_vcpu.guest_cr[4] = c->cr4; vmx_update_guest_cr(v, 0); vmx_update_guest_cr(v, 2); @@ -1846,30 +1859,16 @@ static void vmx_world_save(struct vcpu *v, struct vmx_assist_context *c) static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c) { struct cpu_user_regs *regs = guest_cpu_user_regs(); - unsigned long mfn = 0; - p2m_type_t p2mt; - - if ( c->cr0 & X86_CR0_PG ) - { - mfn = mfn_x(gfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT, &p2mt)); - if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) ) - { - gdprintk(XENLOG_ERR, "Invalid CR3 value=%x", c->cr3); - return -EINVAL; - } - } - - if ( v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PG ) - put_page(pagetable_get_page(v->arch.guest_table)); + int rc; - v->arch.guest_table = pagetable_from_pfn(mfn); + rc = vmx_restore_cr0_cr3(v, c->cr0, c->cr3); + if ( rc ) + return rc; regs->eip = c->eip; regs->esp = c->esp; regs->eflags = c->eflags | 2; - v->arch.hvm_vcpu.guest_cr[0] = c->cr0; - v->arch.hvm_vcpu.guest_cr[3] = c->cr3; v->arch.hvm_vcpu.guest_cr[4] = c->cr4; vmx_update_guest_cr(v, 0); vmx_update_guest_cr(v, 4); @@ -2016,9 +2015,8 @@ static int vmx_assist(struct vcpu *v, int mode) static int vmx_set_cr0(unsigned long value) { struct vcpu *v = current; - int rc = hvm_set_cr0(value); - if ( rc == 0 ) + if ( hvm_set_cr0(value) == 0 ) return 0; /* -- 2.30.2